package org.bear.mario.Pojo;

import org.bear.mario.Running.BackGround;
import org.bear.mario.Running.StaticValue;

import java.awt.image.BufferedImage;

// Mario类表示游戏中的马里奥角色，并实现Runnable接口以支持多线程运行
public class Mario implements Runnable {
    private int x;
    private int y;
    private BackGround bg;
    private Thread t = null;
    private int xmove = 0;
    private int ymove = 0;
    private String status;
    private BufferedImage showImage;
    private int score;
    private int life;
    private int moving = 0;
    private int upTime = 0;
    private boolean isDead = false;
    private boolean isClear = false;

    // 构造函数，初始化马里奥的位置，图像，分数和生命值，并启动线程
    public Mario(int x, int y) {
        this.x = x;
        this.y = y;
        this.showImage = StaticValue.allMarioImage.get(0);
        this.score = 0;
        this.life = 5;

        this.t = new Thread(this);
        t.start();

        this.status = "right-standing";
    }

    // 向左移动马里奥，并更新状态
    public void leftMove() {
        xmove = -5;
        if (this.status.indexOf("jumping") != -1) {
            this.status = "left-jumping";
        } else {
            this.status = "left-moving";
        }
    }

    // 向右移动马里奥，并更新状态
    public void rightMove() {
        xmove = 5;
        if (this.status.indexOf("jumping") != -1) {
            this.status = "right-jumping";
        } else {
            this.status = "right-moving";
        }
    }

    // 停止向左移动，并根据状态更新马里奥站立状态
    public void leftStop() {
        this.xmove = 0;
        if (this.status.indexOf("jumping") != -1) {
            this.status = "left-jumping";
        } else {
            this.status = "left-standing";
        }
    }

    // 停止向右移动，并根据状态更新马里奥站立状态
    public void rightStop() {
        this.xmove = 0;
        if (this.status.indexOf("jumping") != -1) {
            this.status = "right-jumping";
        } else {
            this.status = "right-standing";
        }
    }

    // 执行跳跃操作，更新状态和速度
    public void jump() {
        if (this.status.indexOf("jumping") == -1) {
            if (this.status.indexOf("left") != -1) {
                this.status = "left-jumping";
            } else {
                this.status = "right-jumping";
            }
            ymove = -10;
            upTime = 18;
        }
    }

    // 执行下落操作，并更新状态
    public void down() {
        if (this.status.indexOf("left") != -1) {
            this.status = "left-jumping";
        } else {
            this.status = "right-jumping";
        }
        ymove = 10;
    }

    // 处理马里奥死亡的逻辑，减少生命值
    public void dead() {
        this.life--;
        if (this.life == 0) {
            this.isDead = true;
        } else {
            this.bg.reset();
            this.x = 0;
            this.y = 480;
        }
    }

    // 获取马里奥的横坐标
    public int getX() {
        return x;
    }

    // 获取马里奥的纵坐标
    public int getY() {
        return y;
    }

    // 获取马里奥当前显示的图像
    public BufferedImage getShowImage() {
        return showImage;
    }

    // 运行马里奥的行为逻辑，包括移动，重置和碰撞检测
    public void run() {
        while (true) {
            if (this.bg.isFlag() && this.x >= 520) {
                this.bg.setOver(true);
                if (this.bg.isDown()) {
                    this.status = "right-moving";
                    if (this.x < 580) {
                        this.x += 5;
                    } else {
                        if (this.y < 480) {
                            this.y += 5;
                        }
                        this.x += 5;
                        if (this.x >= 780) {
                            this.setClear(true);
                        }
                    }
                } else {
                    if (this.y < 420) {
                        this.y += 5;
                    }
                    if (this.y >= 420) {
                        this.y = 420;
                        this.status = "right-standing";
                    }
                }
            } else {
                boolean canLeft = true;
                boolean canRight = true;
                boolean onLand = false;

                for (int i = 0; i < this.bg.getAllObstruction().size(); i++) {
                    Obstruction ob = this.bg.getAllObstruction().get(i);
                    if (ob.getX() == this.x + 60 && (ob.getY() + 50 > this.y && ob.getY() - 50 < this.y)) {
                        if (ob.getType() != 3) {
                            canRight = false;
                        }
                    }
                    if (ob.getX() == this.x - 60 && (ob.getY() + 50 > this.y && ob.getY() - 50 < this.y)) {
                        if (ob.getType() != 3) {
                            canLeft = false;
                        }
                    }
                    if (ob.getY() == this.y + 60 && (ob.getX() + 60 > this.x && ob.getX() - 60 < this.x)) {
                        if (ob.getType() != 3) {
                            onLand = true;
                        }
                    }
                    if (ob.getY() == this.y - 60 && (ob.getX() + 50 > this.x && ob.getX() - 50 < this.x)) {
                        if (ob.getType() == 0) {
                            this.bg.getAllObstruction().remove(ob);
                            this.bg.getRemoveObstruction().add(ob);
                        }
                        if ((ob.getType() == 4 || ob.getType() == 3) && upTime > 0) {
                            score += 10;
                            ob.setType(2);
                            ob.setImage();
                        }
                        upTime = 0;
                    }
                }

                for (int i = 0; i < this.bg.getAllEnemy().size(); i++) {
                    Enemy e = this.bg.getAllEnemy().get(i);
                    if ((e.getX() + 50 > this.x && e.getX() - 50 < this.x) && (e.getY() + 60 > this.y && e.getY() - 60 < this.y)) {
                        this.dead();
                    }
                    if (e.getY() == this.y + 60 && (e.getX() + 60 > this.x && e.getX() - 60 < this.x)) {
                        if (e.getType() == 1) {
                            e.dead();
                            this.upTime = 5;
                            this.ymove = -10;
                            score += 10;
                        } else if (e.getType() == 2) {
                            this.dead();
                        }
                    }
                }

                if (onLand && upTime == 0) {
                    if (this.status.indexOf("left") != -1) {
                        if (xmove != 0) {
                            this.status = "left-moving";
                        } else {
                            this.status = "left-standing";
                        }
                    } else {
                        if (xmove != 0) {
                            this.status = "right-moving";
                        } else {
                            this.status = "right-standing";
                        }
                    }
                } else {
                    if (upTime != 0) {
                        upTime--;
                    } else {
                        this.down();
                    }
                    y += ymove;
                }

                if (this.y > 600) {
                    this.dead();
                }

                if (canLeft && xmove < 0 || canRight && xmove > 0) {
                    x += xmove;
                    if (x < 0) {
                        x = 0;
                    }
                }
            }

            int temp = 0;
            if (this.status.indexOf("left") != -1) {
                temp += 5;
            }

            if (this.status.indexOf("moving") != -1) {
                temp += this.moving;
                moving++;
                if (moving == 4) {
                    this.moving = 0;
                }
            }

            if (this.status.indexOf("jumping") != -1) {
                temp += 4;
            }

            this.showImage = StaticValue.allMarioImage.get(temp);

            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // 设置背景对象
    public void setBg(BackGround bg) {
        this.bg = bg;
    }

    // 设置马里奥的横坐标
    public void setX(int x) {
        this.x = x;
    }

    // 设置马里奥的纵坐标
    public void setY(int y) {
        this.y = y;
    }

    // 检查马里奥是否死亡
    public boolean isDead() {
        return isDead;
    }

    // 获取马里奥的分数
    public int getScore() {
        return score;
    }

    // 设置马里奥的分数
    public void setScore(int score) {
        this.score = score;
    }

    // 获取马里奥的生命值
    public int getLife() {
        return life;
    }

    // 设置马里奥的生命值
    public void setLife(int life) {
        this.life = life;
    }

    // 检查游戏是否清关
    public boolean isClear() {
        return isClear;
    }

    // 设置游戏清关状态
    public void setClear(boolean isClear) {
        this.isClear = isClear;
    }
}
